package com.android.fragmentdemo.definervlayoutmanager;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
import com.android.fragmentdemo.adapters.TurnTableAdapter2;
import com.hengfoxwolf.commonbase.base.util.LogX;
import com.hengfoxwolf.commonbase.base.util.ScreenUtil;

public class TurntableLayoutManager extends RecyclerView.LayoutManager {
    private static final String TAG = "TurntableLayoutManager";
    private float mRadius;
    private final float mEachAngle;
    private int mItemWidth;
    private int mItemHeight;

    private static final int BOUND_ANGLE = 60;
    private float mMovedAngle = 0f;

    private int visibleItemIndex = 0;
    private boolean shouldGotIndex = true;

    private boolean canNotScroll = true;

    private RecyclerView recyclerView;

    private Activity activity;

    public TurntableLayoutManager(Activity activity,float mEachAngle) {
        this.activity = activity;
        this.mEachAngle = mEachAngle;
        LogX.INSTANCE.init(TurntableLayoutManager.class);
    }

    @Override
    public void onAttachedToWindow(RecyclerView view) {
        super.onAttachedToWindow(view);
        ScreenUtil.INSTANCE.adapterScreen(activity, activity.getResources().getDisplayMetrics().ydpi, false);
        recyclerView = view;
        LogX.INSTANCE.d("public void onAttachedToWindow");
    }

    @Override
    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
        super.onDetachedFromWindow(view, recycler);
        ScreenUtil.INSTANCE.resetScreen(activity);
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);
        int newItemCount = 0;
        if (recyclerView.getAdapter() != null && recyclerView.getAdapter() instanceof TurnTableAdapter2) {
            Log.d(TAG, "recyclerView.getAdapter() != null");
            newItemCount = ((TurnTableAdapter2) recyclerView.getAdapter()).getItemDataSet() == null ? 0 : ((TurnTableAdapter2) recyclerView.getAdapter()).getItemDataSet().size();
        }
        if (state.isPreLayout()) {
            return;
        }
        Log.d(TAG, "itemCount:" + newItemCount);
        canNotScroll = newItemCount == 0;
        if (canNotScroll && getItemCount() == 1) {
            Log.d(TAG, "getItemCount():" + getItemCount());
            removeAllViews();
            detachAndScrapAttachedViews(recycler);
            View emptyView = recycler.getViewForPosition(0);
            addView(emptyView);
            measureChildWithMargins(emptyView, 0, 0);
            layoutDecorated(emptyView, 0, 0, emptyView.getMeasuredWidth(), emptyView.getMeasuredHeight());
        } else {
            canNotScroll = false;
            initItemSize(recycler);
            removeAllViews();
            detachAndScrapAttachedViews(recycler);
            mRadius = getHeight() * 7.0f / 4;
            int itemCount = getItemCount();
            for (int i = 0; i < itemCount; i++) {
                layoutViewByIndex(recycler, i);
            }
        }
    }

    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (canNotScroll) {
            return 0;
        }
        //Log.d(TAG, "scrollHorizontallyBy---dx:" + dx);
        detachAndScrapAttachedViews(recycler);
        if (dx > 0) {
            mMovedAngle -= convertDxToAngle(dx);
            mMovedAngle = Math.max(mMovedAngle, -getMaxScrollAngle());
        } else {
            mMovedAngle -= convertDxToAngle(dx);
            mMovedAngle = Math.min(0, mMovedAngle);
        }
        //getChildCount()没有被隐藏的数量
        //getItemCount()总数量
        for (int i = 0; i < getItemCount(); i++) {
            layoutViewByIndex(recycler, i);
        }
        //回收view
        recyclerHideView(dx, recycler);
        return dx;
    }

    @Override
    public boolean canScrollHorizontally() {
        return true;
    }

    private int getMaxScrollAngle() {
       if (shouldGotIndex) {
           return 0;
       } else {
           return (int) (Math.min(getItemCount(), Math.max(getItemCount() - visibleItemIndex, 0)) * mEachAngle);
       }
    }

    private float convertDxToAngle(int dx) {
        return (float) (360 * dx / (2 * Math.PI * mRadius));
    }

    private void layoutViewByIndex(RecyclerView.Recycler recycler, int index) {
        float baseRotateAngle = -30f;
        float baseOffsetAngle = 240f;
        //保持初始屏幕内item成对称结构,item才不会缺少或者增加旋转角度.
        //通过baseOffsetAngle与270度的关系保持对称结构,baseRotateAngle与mEachAngle的关系确定初始屏幕内可以对称放置几个item.
        //比如240f(240f 255f 270f 285f 300f),此时mEachAngle为15f,一个屏幕内可以放置5个item.
        float offsetAngle = index * mEachAngle + mMovedAngle;
        if (Math.abs(baseRotateAngle + offsetAngle) <= BOUND_ANGLE) {
            float currentAngle = baseOffsetAngle + offsetAngle;
            double radians = Math.toRadians(currentAngle);
            //-(int) (getWidth() / 2.0f) + getWidth()为x轴的偏移量
            //(int) (getHeight() * 9.0f / 4)为y轴的偏移量
            int xToAdd = (int) (Math.cos(radians) * mRadius) - (int) (getWidth() / 2.0f) + getWidth();
            int yToAdd = (int) (Math.sin(radians) * mRadius) + (int) (getHeight() * 9.0f / 4);
            //Log.d(TAG, "xToAdd:" + xToAdd + ",yToMinus:" + yToMinus);
            View viewForPosition = recycler.getViewForPosition(index);
            addView(viewForPosition);
            measureChildWithMargins(viewForPosition, 0, 0);
            int left = xToAdd - mItemWidth / 2;
            int top = yToAdd - mItemHeight / 2;
            int right = xToAdd + mItemWidth / 2;
            int bottom = yToAdd + mItemHeight / 2;
            layoutDecorated(viewForPosition, left, top, right, bottom);
            if (right > getWidth() && shouldGotIndex) {
                visibleItemIndex = index;
                shouldGotIndex = false;
                Log.d(TAG, "index:" + index);
            }
            //调整旋转角度
            viewForPosition.setRotation(baseRotateAngle + offsetAngle);
        }
    }

    private void initItemSize(RecyclerView.Recycler recycler) {
        View view = recycler.getViewForPosition(0);
        addView(view);
        measureChildWithMargins(view, 0, 0);
        mItemWidth = getDecoratedMeasuredWidth(view);
        mItemHeight = getDecoratedMeasuredHeight(view);
        removeAndRecycleView(view, recycler);
    }

    private void recyclerHideView(int dx, RecyclerView.Recycler recycler) {
        int itemCount = getItemCount();
        for (int i = 0; i < itemCount; i++) {
            View view = getChildAt(i);
            if (view == null) {
                continue;
            }
            if (dx > 0) {
                if (view.getRight() < 0) {
                    removeAndRecycleView(view, recycler);
                }
            } else {
                if (view.getLeft() > getWidth()) {
                    removeAndRecycleView(view, recycler);
                }
            }
        }
    }
}
